package com.bdqn.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
import org.junit.jupiter.api.Test;

/**
 * ShiroTester
 * 认证测试
 * @author f
 * @since 2021/12/11
 *
 */
public class ShiroTester {

    /**
     * 1.首先通过指定一个 ini 配置文件来创建一个 IniRealm 对象；
     * 2.接着实例化一个 DefaultSecurityManager，并注入 IniRealm 对象；
     * 3.再将 DefaultSecurityManager 绑定到 SecurityUtils，这是一个全局设置，设置一次即可；
     * 4.通过 SecurityUtils 得到 Subject；
     * 5.然后获取身份验证的 Token，如用户名 / 密码，此处使用 UsernamePasswordToken；
     * 6.调用 subject.login 方法进行登录，其会自动委托给 SecurityManager.login 方法进行登录；
     * 7.如果身份验证失败请捕获 AuthenticationException 或其子类，常见的如：
     *   DisabledAccountException（禁用的帐号）、LockedAccountException（锁定的帐号）、
     *   UnknownAccountException（错误的帐号）、ExcessiveAttemptsException（登录失败次数
     *   过多）、IncorrectCredentialsException （错误的凭证）、ExpiredCredentialsException（过
     *   期的凭证）等，具体请查看其继承关系；对于页面的错误消息展示，最好使用如 “用
     *   户名 / 密码错误” 而不是 “用户名错误”/“密码错误”，防止一些恶意用户非法扫
     *   描帐号库；
     * 8.如果身份认证成功，后续可以使用 subject.isAuthenticated()判断是否认证通过，
     * subject.getPrincipal()获得身份信息等。
     */
    @Test
    public void testShiro(){
        //1、创建 Realm(安全数据源)
        //通过 shiro.ini 配置文件创建 Realm
        IniRealm realm = new IniRealm("classpath:shiro.ini");
        //2、配置 SecurityManager
        DefaultSecurityManager securityManager = new DefaultSecurityManager();

        //注入创建的 Realm(安全数据源)
        securityManager.setRealm(realm);
        SecurityUtils.setSecurityManager(securityManager);

        //3、操作 Subject，进行认证
        Subject subject = SecurityUtils.getSubject();

        //封装一个令牌
        UsernamePasswordToken token = new UsernamePasswordToken("admin","123456");

        try {
            subject.login(token);//登录，即认证
        } catch (AuthenticationException e) {
            System.out.println("认证异常");
            e.printStackTrace();
        }

        System.out.println("是否认证通过：" + subject.isAuthenticated());
        System.out.println("身份信息：" + subject.getPrincipal());
    }
}
